package tr.edu.metu.is.mega.client.user.profile;

import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.IUploader;
import gwtupload.client.SingleUploader;
import tr.edu.metu.is.mega.client.core.AsyncCallbackAdapter;
import tr.edu.metu.is.mega.client.core.AuthUtils;
import tr.edu.metu.is.mega.client.core.MainWindow;
import tr.edu.metu.is.mega.client.core.QueryCallback;
import tr.edu.metu.is.mega.client.resource.MegaConstants;
import tr.edu.metu.is.mega.client.service.GwtUserService;
import tr.edu.metu.is.mega.client.service.GwtUserServiceAsync;
import tr.edu.metu.is.mega.client.widgets.MegaTextField;
import tr.edu.metu.is.mega.common.dto.UserDTO;
import tr.edu.metu.is.mega.common.dto.UserRole;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.HiddenField;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;

/**
 * Profile window for users.
 */
public class EditProfileWindow extends MainWindow {

    public static final String WINDOW_ID = "ProfileWindow";

    private UserDTO user;

    private final GwtUserServiceAsync gwtUserServiceAsync = GwtUserService.Util.getInstance();

    private final Image profilePhoto = new Image();

    private MegaTextField textFieldUserName;

    private MegaTextField textFieldPassword;

    private MegaTextField textFieldName;

    private MegaTextField textFieldSurname;

    private MegaTextField textFieldEmail;

    private HiddenField<String> textFieldExpiry;

    private MegaTextField textFieldIdentification;

    private FormBinding formBinding;

    private final BeanModelFactory modelFactoryUser;

    /**
     * Default constructor.
     */
    public EditProfileWindow() {
        super(WINDOW_ID, UserDTO.class.getName());
        modelFactoryUser = BeanModelLookup.get().getFactory(UserDTO.class);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onRender(Element parent, int pos) {
        super.onRender(parent, pos);
        setHeading("Edit Profile Information");
        setLayout(new ColumnLayout());

        final SingleUploader defaultUploader = new SingleUploader();
        defaultUploader.addOnFinishUploadHandler(onFinishUploaderHandler);

        AuthUtils.getInstance().getCurrentUser(new QueryCallback<UserDTO>() {

            @Override
            public void onQueryResult(UserDTO result) {
                user = result;
                updatePhoto();
                defaultUploader.setFileInputPrefix(MegaConstants.USER_IMAGES_PATH + user.getUserName().hashCode() + "/");
                formBinding.bind(modelFactoryUser.createModel(result));
            }
        });

        final FormPanel panel = new FormPanel();
        panel.setHeaderVisible(false);
        panel.setBodyBorder(false);

        textFieldUserName = new MegaTextField(UserDTO.FIELD_USERNAME);
        textFieldUserName.setFieldLabel("User Name");
        panel.add(textFieldUserName, new FormData("96%"));

        textFieldPassword = new MegaTextField(UserDTO.FIELD_PASSWORD);
        textFieldPassword.setFieldLabel("Password");
        textFieldPassword.setPassword(true);
        panel.add(textFieldPassword, new FormData("96%"));

        textFieldName = new MegaTextField(UserDTO.FIELD_NAME);
        textFieldName.setFieldLabel("Name");
        panel.add(textFieldName, new FormData("96%"));

        textFieldSurname = new MegaTextField(UserDTO.FIELD_SURNAME);
        textFieldSurname.setFieldLabel("Surname");
        panel.add(textFieldSurname, new FormData("96%"));

        textFieldIdentification = new MegaTextField(UserDTO.FIELD_IDENTIFICATIONNO);
        textFieldIdentification.setFieldLabel("Identification");
        panel.add(textFieldIdentification, new FormData("96%"));

        textFieldEmail = new MegaTextField(UserDTO.FIELD_EMAIL);
        textFieldEmail.setFieldLabel("E-Mail");
        panel.add(textFieldEmail, new FormData("96%"));

        textFieldExpiry = new HiddenField<String>();
        textFieldExpiry.setName(UserDTO.FIELD_EXPIRYDATE);
        panel.add(textFieldExpiry, new FormData("96%"));

        formBinding = new FormBinding(panel);
        formBinding.autoBind();

        UserDTO dto = new UserDTO();
        dto.setRole(UserRole.STUDENT);
        formBinding.bind(BeanModelLookup.get().getFactory(UserDTO.class).createModel(dto));

        Button save = new Button("Save");
        save.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (panel.isValid()) {
                    BeanModel model = (BeanModel) formBinding.getModel();
                    gwtUserServiceAsync.updateUser((UserDTO) model.getBean(), new AsyncCallbackAdapter<UserDTO>() {

                        @Override
                        public void onSuccess(UserDTO result) {
                            AuthUtils.getInstance().updateCurrentUser(user, new QueryCallback<Void>() {

                                @Override
                                public void onQueryResult(Void result) {
                                    Info.display("Ok", "Updated successfully.");
                                }
                            });
                        }
                    });
                }
            }
        });
        panel.addButton(save);
        panel.setButtonAlign(HorizontalAlignment.CENTER);

        LayoutContainer left = new LayoutContainer();
        left.add(profilePhoto);
        left.add(defaultUploader);
        left.setStyleAttribute("paddingLeft", "30px");
        this.add(left, new ColumnData(0.5));
        this.add(panel, new ColumnData(0.4));

    }

    /**
     * Updates photo of current user.
     */
    private void updatePhoto() {
        // profilePhoto.setUrlAndVisibleRect(MegaConstants.USER_IMAGES_PATH +
        // user.getPhoto(), 0, 0, 200, 200);
        if (user.getPhoto() != null) {
            profilePhoto.setUrl(MegaConstants.USER_IMAGES_PATH + user.getUserName().hashCode() + "/" + user.getPhoto());
        } else {
            profilePhoto.setUrl(MegaConstants.EMPTY_USER_IMAGE_PATH);
        }
        profilePhoto.setWidth("300px");
    }

    private final IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {

        @Override
        public void onFinish(IUploader uploader) {
            if (uploader.getStatus() == Status.SUCCESS) {
                user.setPhoto(uploader.getServerInfo().message);
                gwtUserServiceAsync.updateUser(user, new AsyncCallback<UserDTO>() {

                    @Override
                    public void onSuccess(UserDTO result) {
                        AuthUtils.getInstance().updateCurrentUser(user, new QueryCallback<Void>() {

                            @Override
                            public void onQueryResult(Void result) {
                                updatePhoto();
                            }
                        });
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                    }
                });

            }
        }
    };

}
